#pragma once

#include <functional>
#include <cstdio>
#include <atomic>
#include <string>
#include <sys/epoll.h>

#include <sys/types.h>
#include <sys/socket.h>

#include "logger/logger.hpp"
#include "nanomsg/nn.h"
#include "nanomsg/pair.h"
#include "nanomsg/pubsub.h"
#include "nanomsg/pipeline.h"
#include "nanomsg/tcp.h"

class SmartNetPair
{
public:
    enum FS {
        NP_NONE,
        NP_SERVER,
        NP_CLIENT
    };

public:
    SmartNetPair(enum FS fs, std::string sockUrl) : m_fs(fs), m_sockUrl(sockUrl) {}
    ~SmartNetPair() {
        deinit();
    }

    int init() {
        if (NP_SERVER == m_fs) {
            return init_server();
        }
        else if (NP_CLIENT == m_fs) {
            return init_client();
        }
        else {
            LOG_ERROR("network_pair init failed.\n");
            exit(EXIT_FAILURE);
        }
        
        return -1;
    }

    int deinit();

    int stop(void) {
        m_loop_run = false;
        return 0;
    }

    int send_mesg(uint8_t *data, uint32_t len);
    int loop_recv_mesg(std::function<void(uint8_t *, uint32_t)> callback);

private:
    int init_server();
    int init_client();

private:
    enum FS m_fs{NP_NONE};
    std::string m_sockUrl;
    int m_sockFd{-1};
    std::atomic_bool m_loop_run{false};
};